//
//  ArticleListReactor.swift
//  WanAndroidLearn
//
//  Created by TRS-Mobile on 2023/11/3.
//

import Foundation
import ReactorKit

class ArticleListReactor: Reactor {
    enum Action {
        case refresh
        case loadMore
    }
    
    enum Mutation {
        case setRefreshing(Bool)
        case setLoading(Bool)
        case clearDatas
        case addArticles([ArticleListCellReactor])
    }
    
    struct State {
        var page: Int = 0
        var isRefreshing: Bool = false
        var isLoading: Bool = false
        var items: [ArticleListCellReactor] = []
    }
    var initialState: State = State()
    
    func mutate(action: Action) -> Observable<Mutation> {
        switch action {
        case .refresh:
            guard !self.currentState.isRefreshing else {
                return .empty()
            }
            guard !self.currentState.isLoading else {
                return .empty()
            }
            let startRefrehing = Observable.just(Mutation.setRefreshing(true))
            let endRefreshing = Observable.just(Mutation.setRefreshing(false))
            let list = request(page: 0)
                .startWith(.clearDatas)
            
            return .concat([startRefrehing, list, endRefreshing])
        case .loadMore:
            guard !self.currentState.isRefreshing else {
                return .empty()
            }
            guard !self.currentState.isLoading else {
                return .empty()
            }
            let startRefrehing = Observable.just(Mutation.setLoading(true))
            let endRefreshing = Observable.just(Mutation.setLoading(false))
            let list = request(page: self.currentState.page)
            
            return .concat([startRefrehing, list, endRefreshing])
        }
    }
    
    func request(page: Int) -> Observable<Mutation> {
        return networking
            .request(.articleList(page: page, cid: nil, author: nil))
            .asObservable()
            .map(WanResponseData<Article>.self)
            .map {
                $0.data.datas
            }
            .map {
                $0.map(ArticleListCellReactor.init(article: ))
            }
            .map {
                Mutation.addArticles($0)
            }
    }
    
    func reduce(state: State, mutation: Mutation) -> State {
        var state = state
        switch mutation {
        case .addArticles(let array):
            state.page += 1
            state.items.append(contentsOf: array)
        case .setRefreshing(let isRefreshing):
            state.isRefreshing = isRefreshing
        case .setLoading(let isLoading):
            state.isLoading = isLoading
        case .clearDatas:
            state.page = 0
            state.items = []
        }
        return state
    }
}
